package com.seestech.sell.common.utils;

import com.seestech.sell.domain.model.ThemeColumn;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * Created by idiot on 2017/1/14.
 * @description xml相关工具类
 */
public class XMLUtils {
    private static Logger logger = LoggerFactory.getLogger(XMLUtils.class);

    /**
     * @description 根据路径读取主题栏目  xml信息
     * @param path
     * @return
     * @throws MalformedURLException
     * @throws DocumentException
     */
    public static List<ThemeColumn> readXML(String path) throws MalformedURLException, DocumentException {
        logger.info("读取xml文件信息===>开始");
        List<ThemeColumn> list = new ArrayList<>();
        Document document = getXMLDocument(path);
        Element root = getRoot(document);
        Iterator it = getXMLIterator(root);
        while (it.hasNext()){
            Element element = (Element) it.next();
            //获取该节点下面的所有属性
            List<Attribute> atrributes = element.attributes();
            //遍历属性
            ThemeColumn info = new ThemeColumn();
            for (Attribute atrribute : atrributes){
                String name = atrribute.getName();
                if(atrribute.getValue() != "") {
                    switch (name) {
                        case "code":
                            info.setColumnCode(atrribute.getValue());
                            break;
                        case "name":
                            info.setColumnName(atrribute.getValue());
                            break;
                        case "type":
                            info.setColumnType(Integer.parseInt(atrribute.getValue()));
                            break;
                        case "rank":
                            info.setDisplayIndex(Integer.parseInt(atrribute.getValue()));
                            break;
                        default:
                            break;
                    }
                }
            }
            list.add(info);
        }
        logger.info("读取xml文件信息===>结束");
        return list;
    }


    /**
     * @description  根据操作符 修改index.xml
     * @param operate
     * @param themeColumns
     */
    public static void operateXML(String operate, List<ThemeColumn> themeColumns, String path) throws IOException, DocumentException, TransformerException {
        switch (operate){
            case "insert":
                insertXML(themeColumns, path);
                break;
            case "update":
                updateXML(themeColumns, path);
                break;
            case "delete":
                deleteXML(themeColumns, path);
                break;
            default:
                break;
        }
    }

    /**
     * @description 删除xml里面的部分信息
     * @param themeColumns
     * @param path
     * @throws IOException
     * @throws DocumentException
     * @throws TransformerException
     */
    private static void deleteXML(List<ThemeColumn> themeColumns, String path) throws IOException, DocumentException, TransformerException {
        logger.info("删除xml文件部分信息=====>开始");
        //获取xml文档对象
        Document document = getXMLDocument(path);
        Element root = getRoot(document);
        Iterator it = getXMLIterator(root);
        //遍历xml节点
        while (it.hasNext()){
            Element element = (Element) it.next();  //获取元素
            //获取该节点下面的所有属性
            List<Attribute> atrributes = element.attributes();
            //遍历属性
            for (Attribute atrribute : atrributes){
                String name = atrribute.getName();
                //判断元素节点名称  匹配code
                if("code".equals(name)){
                    //遍历主题栏目信息  一旦匹配  移除xml文档对象
                    for (ThemeColumn themeColumn : themeColumns){
                        if(themeColumn.getColumnCode() != null && themeColumn.getColumnCode().equals(atrribute.getValue())){
                            root.remove(element);       //利用父级元素移除当前元素
                            it = getXMLIterator(root);  //重新获取元素
                            break;
                        }
                    }
                }
            }
        }
        //重新保存文件
        if(!saveXMLDocumentToFile(document, "UTF-8", path)){
            logger.error("更新xml文件失败");
        }
        logger.info("删除xml文件部分信息=====>结束");
    }

    /**
     * @description  修改xml
     * @param themeColumns
     * @param path
     * @throws MalformedURLException
     * @throws DocumentException
     */
    private static void updateXML(List<ThemeColumn> themeColumns, String path) throws MalformedURLException, DocumentException {
        logger.info("修改xml文件部分信息=====>开始");
        //获取xml文档对象
        Document document = getXMLDocument(path);
        Element root = getRoot(document);
        Iterator it = getXMLIterator(root);
        //遍历xml节点
        while (it.hasNext()){
            Element element = (Element) it.next();  //获取元素
            //获取该节点下面的所有属性
            List<Attribute> atrributes = element.attributes();
            boolean updateElement = false;
            //遍历属性
            for (Attribute atrribute : atrributes){
                String name = atrribute.getName();
                for (ThemeColumn info : themeColumns){
                    if("code".equals(name)){    //读取属性  匹配code属性
                        //修改该元素上的属性
                        updateElement = true;
                    }
                    if(updateElement){
                        //开始修改该元素的属性
                        switch (name) {
                            case "code":
                                atrribute.setValue(info.getColumnCode());
                                break;
                            case "name":
                                atrribute.setValue(info.getColumnName());
                                break;
                            case "type":
                                atrribute.setValue(info.getColumnType().toString());
                                break;
                            case "rank":
                                atrribute.setValue(info.getDisplayIndex().toString());
                                break;
                            default:
                                break;
                        }
                    }
                }

            }
        }
        //重新保存文件
        if(!saveXMLDocumentToFile(document, "UTF-8", path)){
            logger.error("更新xml文件失败");
        }
        logger.info("修改xml文件部分信息=====>结束");
    }

    private static void insertXML(List<ThemeColumn> themeColumns, String path) {
    }

    /**
     * @description
     * @param path
     * @return
     * @throws MalformedURLException
     * @throws DocumentException
     */
    public static Document getXMLDocument(String path) throws MalformedURLException, DocumentException {
        logger.info("获取xml文件的document对象");
        SAXReader reader = new SAXReader();
        //获取文档对象
        Document document = reader.read(new File(path));
        return document;
    }

    /**
     * @description  根据document对象获取根节点
     * @param document
     * @return
     */
    public static Element getRoot(Document document){
        logger.info("获取xml文件的根节点");
        //获取根节点
        Element root = document.getRootElement();
        return root;
    }

    /**
     * @description 获取xml文件里面的根节点下的子节点
     * @return      iterator迭代对象
     * @param root
     */
    public static Iterator getXMLIterator(Element root) {
        logger.info("获取xml文件里面的根节点下的子节点");
        //遍历根节点
        Iterator it = root.elementIterator();
        return it;
    }

    public static void generateXML(List<ThemeColumn> list, String filePath){
        // 使用DocumentHelper类创建一个Document对象
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("root");     //根节点
        //设置根节点属性
        root.addAttribute("lastupdate", DateUtils.getTime(DateUtils.SIMPLE_DATE_HOURS_PATTERN));
        root.addAttribute("width", "1080");
        root.addAttribute("height", "1920");
        //遍历集合添加属性
        for(ThemeColumn themeColumn : list){
            if(themeColumn.getDirectoryId() != null){
                Element column = root.addElement("column"); //子节点  column
                column.addAttribute("code", themeColumn.getColumnCode());   //code
                column.addAttribute("name", themeColumn.getColumnName());   //name
                column.addAttribute("fold", themeColumn.getFold());   //fold
                column.addAttribute("type", themeColumn.getColumnType().toString());   //type
                column.addAttribute("rank", themeColumn.getDisplayIndex().toString());   //rank
            }
        }
        saveXMLDocumentToFile(document, "UTF-8", filePath);
    }


    /**
     * 创建xml格式的文件
     * @param doc
     * @param encoding
     * @param strFileName
     * @return
     */
    public static boolean saveXMLDocumentToFile(Document doc, String encoding, String strFileName) {
        boolean flag = false;
        // 创建路径
        if (encoding == null || encoding.length() == 0) {
            encoding = "UTF-8";
        }
        OutputFormat outputFormat = new OutputFormat();
        outputFormat.setEncoding(encoding);
        FileOutputStream fos = null;
        XMLWriter xmlWriter = null;
        try {
            fos = new FileOutputStream(strFileName);// 可解决UTF-8编码问题
            xmlWriter = new XMLWriter(fos, outputFormat);
            xmlWriter.write(doc);
            flag = true;
        } catch (IOException e) {
            flag = false;
            logger.error("保存xml文件出错：" + e.getMessage());
        } finally {
            try {
                if (xmlWriter != null) {
                    xmlWriter.flush();
                }
                if (fos != null) {
                    fos.flush();
                }
                if (xmlWriter != null) {
                    xmlWriter.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
        return flag;
    }

}
